1

const Cu = Components.utils;
const Ci = Components.interfaces;
const Cc = Components.classes;
function require(url) {
    let scope = {};
    Cu.import(url, scope);
    return scope;
}
let {pm} = require("chrome://jsm/content/passwordManager.js")
let {Prefs} = require("chrome://jsm/content/Preferences.js");
let {RequestWatcher} = require("chrome://jsm/content/requestWatcher.js");
let {SOAPClient} = require("chrome://jsm/content/SOAPClient.js");
let {Services} = require("resource://gre/modules/Services.jsm");
let {OS} = require("resource://gre/modules/osfile.jsm");
let {Dialogs} = require("chrome://jsm/content/Dialogs.js");





function initGeneralPane() {
    
    let delayval = Prefs.replayingDelay;
    let elem = null;
    if  (delayval <= 100 || isNaN(delayval) ) {
        elem = document.getElementById('delayfast');
    } else if (delayval <= 1000) {
        elem = document.getElementById('delaymedium');
    } else {
        elem = document.getElementById('delayslow');
    }
    var radiogrp = document.getElementById("replay-speed");
    radiogrp.selectedItem = elem;
    
    
    document.getElementById("scroll").checked = Prefs.scrollToElement;
    document.getElementById("highlight").checked = Prefs.highlightElement;
    document.getElementById("showjs").checked = Prefs.visualizeJavascript;

    
    document.getElementById("use-toggle-hotkey").checked = 
        Prefs.useToggleHotkey;

    
    document.getElementById("maxwait").value = Prefs.pageTimeout;

    document.getElementById("profiler-enabled").checked =
        Prefs.profilerEnabled;
}

function setShortcuts() {
    Prefs.useToggleHotkey = 
        document.getElementById("use-toggle-hotkey").checked;

    
    
    

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
}

function setGeneralPane() {
    
    if  ( document.getElementById('delayfast').selected) {
        Prefs.replayingDelay = 0;
    } else if (document.getElementById('delaymedium').selected) {
        Prefs.replayingDelay = 1000;
    } else {
        Prefs.replayingDelay = 2000;
    }

    
    Prefs.scrollToElement = document.getElementById("scroll").checked;
    Prefs.highlightElement = document.getElementById("highlight").checked;
    Prefs.visualizeJavascript = document.getElementById("showjs").checked;

    
    setShortcuts();
    
    
    let maxwait = document.getElementById("maxwait");
    if (/^\d+$/.test(maxwait.value))
        Prefs.pageTimeout = parseInt(maxwait.value);
    
    
    Prefs.profilerEnabled = document.getElementById("profiler-enabled").checked;
}





function initSecurityPane() {
    
    let sec = document.getElementById("sec"+pm.encryptionType.toString());
    let pwdusage = document.getElementById("masterpwd-usage");
    pwdusage.selectedItem = sec;
    updatePasswordControls(pm.encryptionType);
    let sec2master = document.getElementById("sec2master");
    try {
        sec2master.value = pm.getMasterPwd();
    } catch(x) {
        
    }
}




function updatePasswordControls(val) {
    if (!/^[123]$/.test(val.toString()))
        val = 1;
    pm.encryptionType = val;
    let sec2master = document.getElementById("sec2master");
    let tmp_master = document.getElementById('tmp-master');
    if (val == 1) {
        sec2master.disabled = true;
        tmp_master.disabled = true;
    } else if (val == 2) {
        sec2master.disabled = null;
        tmp_master.disabled = true;
        sec2master.focus();
    } else if (val == 3) {
        sec2master.disabled = true;
        tmp_master.disabled = null;
        tmp_master.focus();
    }
}



function enterTempPassword() {
    const enter_temp = "Enter temporary key (it will be available as "+
          "long as iMacros is active)";
    let password = {value: pm.getSessionPwd()};
    let ok = Services.prompt.promptPassword(
        window, "iMacros", enter_temp,
        password, null, {}
    );
    if (ok)
        pm.setSessionPwd(password.value);
}

function setSecurityPane() {
    
    if (pm.encryptionType == pm.TYPE_STORED) {
        let sec2master = document.getElementById("sec2master");
        if (!sec2master.value) {
            alert("Master password can not be empty!");
            sec2master.focus();
            return;
        }
        pm.setMasterPwd(sec2master.value);
    }
}




function initPathPane() {
    
    let epath = document.getElementById('editpath');
    let ebtn = document.getElementById('editpathbtn');
    let chkeditor = document.getElementById('chkeditor');
    if (Prefs.useExternalEditor) {
        chkeditor.checked = true;
        epath.disabled = null;
        ebtn.disabled = null;
    } else {
        chkeditor.checked = false;
        epath.disabled = true;
        ebtn.disabled = true;
    }
    
    epath.value  = Prefs.externalEditorPath;

    
    document.getElementById("savepath").value = 
        Prefs.defaultMacroPath;
    document.getElementById("datapath").value = 
        Prefs.defaultDataPath;
    document.getElementById("downpath").value = 
        Prefs.defaultDownloadPath;

    let store_check = document.getElementById("store-in-profile");
    if (Prefs.storeMacrosInProfile) {
        store_check.checked = true;
        disablePathsBoxes(true);
    } else {
        store_check.checked = false;
        disablePathsBoxes(null);
    }
}

function browseForFile(prefname, element_id) {
    Dialogs.browseForFileOpen("iMacros", Prefs[prefname]).then( path => {
        if (path){
            document.getElementById(element_id).value = path;
            Prefs[prefname] = path;
        }
    }).catch(e => Cu.reportError(e));
}

function browseForFolder(prefname, element_id) {
    Dialogs.browseForFolder("iMacros", Prefs[prefname]).then( path => {
        if (path) {
            document.getElementById(element_id).value = path;
            Prefs[prefname] = path;
        }
    }).catch(e => Cu.reportError(e));
}


function updateEditorField() {
    let path = document.getElementById('editpath');
    let btn = document.getElementById('editpathbtn');
    let chkbox = document.getElementById('chkeditor');
    if (!chkbox.checked) {   
        path.disabled = true;
        btn.disabled = true;
    } else {
        path.disabled = null;
        btn.disabled = null;
        path.focus();
    }
}



function disablePathsBoxes(val) {
    let paths = ["savepath", 
                 "datapath", "downpath"];
    for (let path of paths) {
        let p = document.getElementById(path);
        let b = document.getElementById("browse-"+path);
        p.disabled = val || null;
        b.disabled = val || null;
    }
}


function storeInProfile() {
    
    let store_check = document.getElementById('store-in-profile');
    Prefs.storeMacrosInProfile = store_check.checked;
    disablePathsBoxes(store_check.checked);

    document.getElementById("savepath").value = 
        Prefs.defaultMacroPath;
    document.getElementById("datapath").value = 
        Prefs.defaultDataPath;
    document.getElementById("downpath").value = 
        Prefs.defaultDownloadPath;

    if (store_check.checked) 
        return;
    
    let paths = ["savepath", "datapath", "downpath"];
    let pref_names = ["defaultMacroPath", "defaultDataPath",
                      "defaultDownloadPath"];
    Promise.all(paths.map(path => {
        return validatePath(document.getElementById(path).value);
    })).then(normalized_paths => {
        for (let i = 0; i < paths.length; i++) {
            document.getElementById(paths[i]).value = normalized_paths[i];
            
        }
        
        let enumerator = Services.wm.getEnumerator("navigator:browser");
        while(enumerator.hasMoreElements()) {
            let win = enumerator.getNext();
            if (win.sidebar && win.sidebar.initMTree)
                win.sidebar.initMTree();
        }
    });
}

function validatePath(path) {
    return new Promise((resolve, reject) => {
        try {
            var x = OS.Path.normalize(path);
        } catch (e) {
            window.alert("Incorrect path '"+path+"'!");
            return reject(e);
        }
        
        OS.File.exists(x).then( exists => {
            if (!exists) {
                window.alert("Path '"+path+"' does not exist!");
                reject();
            } else {
                resolve(x);
            }
        })
    });
}


function storePreferencesOnPathPane() {
    return new Promise((resolve, reject) => {
        
        let chkeditor = document.getElementById('chkeditor');
        if ((Prefs.useExternalEditor = chkeditor.checked)) {
            validatePath(document.getElementById('editpath').value)
                .then(path => Prefs.externalEditorPath = path)
                .catch(reject);
        } 

        
        if (Prefs.storeMacrosInProfile)
            return resolve();

        let paths = ["savepath", "datapath", "downpath"];
        let pref_names = ["defaultMacroPath", "defaultDataPath",
                          "defaultDownloadPath"];
        Promise.all(paths.map(path => {
            return validatePath(document.getElementById(path).value);
        })).then(normalized_paths => {
            for (let i = 0; i < pref_names.length; i++)
                Prefs[pref_names[i]] = normalized_paths[i];
            
            let enumerator = Services.wm.getEnumerator("navigator:browser");
            while(enumerator.hasMoreElements()) {
                let win = enumerator.getNext();
                if (win.sidebar && win.sidebar.initMTree)
                    win.sidebar.initMTree();
            }
            resolve();
        }).catch(reject);
    });
}


function lookAt(folder) {
    
}





function onSelectWhiteList() {
    var wlist = document.getElementById("white-list");
    var btn_remove = document.getElementById("remove-site");
    var btn_toggle = document.getElementById("toggle-site");

    btn_remove.disabled = null;
    btn_toggle.disabled = null;

    var item = wlist.selectedItem;
    if (!item)
        return;
    var state = item.lastChild.getAttribute("label");
    if (state == "allowed") {
        btn_toggle.label = "Block";
    } else {
        btn_toggle.label = "Allow";
    }
}

function onTextBoxKeypress(evt) {
    const VK_ENTER = Ci.nsIDOMKeyEvent.DOM_VK_ENTER;
    const VK_RETURN = Ci.nsIDOMKeyEvent.DOM_VK_RETURN;

    if (evt.keyCode == VK_RETURN || evt.keyCode == VK_ENTER) {
        addSite();
        evt.preventDefault();
    }
}


function onListKeydown(evt) {
    const VK_DELETE = Ci.nsIDOMKeyEvent.DOM_VK_DELETE;
    
    if (evt.keyCode == VK_DELETE) {
        removeSites();
        evt.preventDefault();
    } 
}


function onListDblClick(evt) {
    if (evt.button == 0)
        toggleSite();
}


function checkSiteSpelling(site) {
    var arr = null;
    if (arr = site.match(/^(\w+):\/\/([\w.]+)\/(\S*)$/)) {
        return arr[2];
    } else if (arr = site.match(/^([\w-]+(\.[\w-]+)+)\/?.*$/)) {
        return arr[1];
    } else {
        
        alert("The value entered must be a valid URL or domain name (e.g. www.example.com)");
        return null;
    }
}



function fillList(sortorder) {
    let wlist = document.getElementById("white-list");
    let sites = RequestWatcher.enumerateSites();
    let ascending = (x, y) => x.site.localeCompare(y.site);
    let descending = (x, y) => y.site.localeCompare(x.site);
    if (typeof sortorder == "undefined")
        sortorder = "a";        
    sites.sort(sortorder == "a" ? ascending : descending);

    
    while( wlist.getRowCount() )
        wlist.removeItemAt(0);
    for (let s of sites) {
        let li = document.createElement("listitem");
        let lc_site = document.createElement("listcell");
        lc_site.setAttribute("label", s.site);
        lc_site.setAttribute("tooltiptext",
                             "Double click on the item changes its status");
        var lc_status = document.createElement("listcell");
        lc_status.setAttribute("label", s.blocked? "blocked" : "allowed");
        li.appendChild(lc_site);
        li.appendChild(lc_status);
        wlist.appendChild(li);
    }
}

function addSite() {
    var textbox = document.getElementById("add-site-textbox");
    var site = checkSiteSpelling(textbox.value);
    if (!site) {
        textbox.focus();
        textbox.select();
        return;
    }

    RequestWatcher.addSite(site);
    textbox.value = "";
    textbox.popupOpen = false;
    fillList();
}


function removeSites() {
    var wlist = document.getElementById("white-list");

    for (var i = 0; i < wlist.selectedCount; i++) {
        var li = wlist.getSelectedItem(i);
        var site = li.firstChild.getAttribute("label");
        RequestWatcher.removeSite(site);
    }
    fillList();
}


function toggleSite() {
    var wlist = document.getElementById("white-list");
    var btn_toggle = document.getElementById("toggle-site");

    var li = wlist.selectedItem;
    var site = li.firstChild.getAttribute("label");
    var status = li.lastChild.getAttribute("label");
    
    if (status == "allowed") {
        RequestWatcher.blockSite(site);
        li.lastChild.setAttribute("label", "blocked");
        btn_toggle.label = "Allow";
    } else {
        RequestWatcher.addSite(site);
        li.lastChild.setAttribute("label", "allowed");
        btn_toggle.label = "Block";
    }
}

function initScriptsPane() {
    
    fillList();
}







function editCommandsList() {
    var param = {};
    window.openDialog("chrome://imacros/content/warncmds.xul",
                      "", "modal,centerscreen", param);
}

function enableAFSupport(enable) {
    var enabled_chkbox = document.getElementById("af-enable-support");
    var runtime_chkbox = document.getElementById("af-warn-runtime");
    var runtime_value = document.getElementById("af-runtime-value");
    var commands_chkbox = document.getElementById("af-warn-commands");
    var commands_btn = document.getElementById("af-edit-commands");

    enable = typeof(enable) == "undefined" ? enabled_chkbox.checked : enable;
    if (enable) {
        runtime_chkbox.disabled = null;
        runtime_value.disabled = null;
        commands_chkbox.disabled = null;
        commands_btn.disabled = null;
    } else {
        runtime_chkbox.disabled = true;
        runtime_value.disabled = true;
        commands_chkbox.disabled = true;
        commands_btn.disabled = true;
    }
}


var g_af_logins = {};

function onAfLoginChange(evt) {
    var usr_deck = document.getElementById("af-username-deck");
    var btn = document.getElementById("af-check-credentials-btn");
    btn.image = "";
    if (evt.target.id == "af-password-box")
        return;
    if (usr_deck.selectedIndex == 1) {
        var pwd_box = document.getElementById("af-password-box");
        pwd_box.value = g_af_logins[usr_deck.selectedPanel.value];
    } else if (usr_deck.selectedIndex == 0) {
        
    }
}

function initCloudServicesPane() {
    
    let usr_deck = document.getElementById("af-username-deck");
    let pwd_box = document.getElementById("af-password-box");
    const AF_auth_host = "https://my.alertfox.com";
    let logins = Services.logins.findLogins({}, AF_auth_host, "", null);
    if (logins.length == 1) {
        usr_deck.selectedIndex = 0;
        usr_deck.selectedPanel.value = logins[0].username;
        pwd_box.value = logins[0].password;
    } else if (logins.length > 1) {
        usr_deck.selectedIndex = 1;
        var ml = usr_deck.selectedPanel, idx = 0;
        for (var i = 0; i < logins.length; i++) {
            var uname = logins[i].username;
            g_af_logins[uname] = logins[i].password;
            ml.appendItem(uname, uname, "");
            if (Prefs.AlertFoxUserName == uname) {
                idx = i;
            }
        }
        ml.selectedIndex = idx;
        pwd_box.value = g_af_logins[ml.value];
    }

    
    
    

    
    

    
    

    
    
}


function setCloudServicesPane() {
    var usr_deck = document.getElementById("af-username-deck");
    var pwd_box = document.getElementById("af-password-box");
    if (!pwd_box.value)
	return;
    const AF_auth_host = "https://my.alertfox.com";
    var nsLoginInfo = new Components.
        Constructor("@mozilla.org/login-manager/loginInfo;1",
                    Ci.nsILoginInfo, "init");
    let new_login = new nsLoginInfo(
        AF_auth_host, AF_auth_host+"/login.aspx", null,
        usr_deck.selectedPanel.value, pwd_box.value, "", ""
    );
    Prefs.AlertFoxUserName = usr_deck.selectedPanel.value;
    let logins = Services.logins.findLogins({}, AF_auth_host, "", null);
    let found = false;
    for (let login of logins) {
        if (login.username == new_login.username) {
            if (login.password != new_login.password)
                Services.logins.removeLogin(login);
            else
                found = true;
            break;
        }
    }
    
    if (!found)
        Services.logins.addLogin(new_login);
}


function checkAfCredentials () {
    var btn = document.getElementById("af-check-credentials-btn");
    const wsdl_url = "https://my.alertfox.com/imu/AlertFoxManagementAPI.asmx";
    var uname = document.getElementById("af-username-deck").selectedPanel.value;
    var pwd = document.getElementById("af-password-box").value;
    var args = {accountName: uname, accountPassword: pwd};

    
    btn.disabled = true;
    btn.image = "chrome://imacros/skin/waiting_16x16.gif";
    SOAPClient.invoke(wsdl_url, "CheckLogin", args).then(rv => {
        
        btn.image = "";
        btn.disabled = null;
        
        if (!rv) {
            alert("Error occured while checking credentials: "+
                  err.message);
            return;
        }
        if (rv.CheckLoginResult) {
            btn.image = "chrome://imacros/skin/check_ok_16x16.png";
        } else {
            alert("Either user name or password is incorrect");
        }
    }).catch(e => Cu.reportError(e));
}


window.onload = function () { 
    try {
        if (window.arguments && window.arguments[0].pane) {
            var pane = document.getElementById(window.arguments[0].pane);
            if (pane) {
                var pw = document.getElementById("imacros-options-dialog");
                pw.showPane(pane);
            }
        }

        initGeneralPane();
        initSecurityPane();
        initPathPane();
        initScriptsPane();                
        initCloudServicesPane();
        sizeToContent();
    } catch(e) {
        Components.utils.reportError(e);
    }
};






function do_accept () {       
    Promise.resolve().then(() => {
        setGeneralPane();
        setSecurityPane();
        setCloudServicesPane();
        return storePreferencesOnPathPane();
    }).catch(e => {
        Cu.reportError(e);
    }).then(() => {
        window.close();
    });
}

